package com.wenlong.train_ticketing_system_springboot.querymodule.consumer;

import com.rabbitmq.client.Channel;
import com.wenlong.train_ticketing_system_springboot.querymodule.config.RabbitConfig;
import com.wenlong.train_ticketing_system_springboot.querymodule.service.OrderService;
import com.wenlong.train_ticketing_system_springboot.querymodule.service.TicketService;
import com.wenlong.train_ticketing_system_springboot.querymodule.websocketCom.WebSocketServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * @author 苏文龙
 * @version 1.0
 */
@Component
@Slf4j
//@RabbitListener(queues = {RabbitConfig.DELAY_MSG_QUEUE})
public class RabbitConsultConsumer {

    @Autowired
    private WebSocketServerEndpoint webSocketServerEndpoint;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private TicketService ticketService;
    @Autowired
    private OrderService orderService;

    /**
     * 定时消息队列消费监听进行消息提醒
     * @param content
     * @param message
     * @param channel
     * @throws IOException
     */
//    @RabbitHandler
    @RabbitListener(queues = {RabbitConfig.DELAY_MSG_QUEUE})
    public void receiveDelayQueue(String content, Message message, Channel channel) throws IOException {
//        log.info("----------------接收延迟队列消息--------------------");
        //通知 MQ 消息已被接收,可以ACK(从队列中删除)了
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        try {
            log.info("接收到的内容为: {}", content);
            //发送给WebSocket 由WebSocket推送给前端
            webSocketServerEndpoint.sendMessageOnline(content);
        } catch (Exception e) {
            log.error("============消费失败,尝试消息补发再次消费!==============");
            log.error(e.getMessage());
            /**
             * basicRecover方法是进行补发操作，
             * 其中的参数如果为true是把消息退回到queue但是有可能被其它的consumer(集群)接收到，
             * 设置为false是只补发给当前的consumer
             */
            channel.basicRecover(false);
        }
    }

    /**
     * 判断 Redis 中有没有已经过期的订单, 有的话就将他进行删除
     * @param content
     * @param message
     * @param channel
     * @throws IOException
     */
    @RabbitListener(queues = {RabbitConfig.DELAY_MSG_DELETE_QUEUE})
    public void receiveDelayQueueToDeleteMsg(String content, Message message, Channel channel) throws IOException {
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        try {
            String obj = (String) redisTemplate.opsForValue().get(content);
            if (obj != null) {
                orderService.removeById(content);
                webSocketServerEndpoint.sendMessageOnline("订单号为:" + content +"的订单已经过期!!");
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            channel.basicRecover(false);
        }
    }
}
